﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace Com.OpenCode.DwgConvert.Model
{
    /// <summary>
    /// 抽象基类
    /// 避免将dwg类库中的对象定义成属性
    /// 会引起莫名其妙的null point错误
    /// </summary>
    public abstract class AbstractDataConvert : IDataConvert
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public AbstractDataConvert()
        {
            TaskStatus = TaskStatus.Checked;
            DataConvertLog = new DataConvertLog();
            AddInfoLogItem("开始创建任务");
        }

        /// <summary>
        /// 任务类型
        /// </summary>
        public virtual TaskType TaskType { get; protected set; }

        /// <summary>
        ///输入的数据源
        /// </summary>
        public TaskDatasource InputDatasource { get; set; }

        /// <summary>
        /// 输出的数据源
        /// </summary>
        public TaskDatasource OutputDatasource { get; set; }

        /// <summary>
        /// 转换参数接口
        /// </summary>
        public virtual IConvertParams ConvertParams { get; set; }

        /// <summary>
        /// 任务名称
        /// </summary>
        public virtual string Name { get; protected set; }

        /// <summary>
        /// 任务的描述信息
        /// </summary>
        public virtual string Description { get; protected set; }

        /// <summary>
        /// 任务执行的状态
        /// </summary>
        public TaskStatus TaskStatus { get; protected set; }

        /// <summary>
        /// 获取或设置绑定的对象
        /// 改对象的目的是用来绑定对应的展示层ui
        /// </summary>
        public object Binding { get; set; }

        /// <summary>
        /// 日志接口对象
        /// </summary>
        public IDataConvertLog DataConvertLog { get; protected set; }

        /// <summary>
        /// 检查前事件
        /// </summary>
        public event DataConvertDelegate BeforeCheck;

        /// <summary>
        /// 检查完成事件
        /// </summary>
        public event DataConvertDelegate AfterCheck;

        /// <summary>
        /// 检查中事件
        /// </summary>
        public event DataConvertProcessDelegate Checking;

        /// <summary>
        /// 转换前事件
        /// </summary>
        public event DataConvertDelegate BeforeConvert;

        /// <summary>
        /// 转换完成事件
        /// </summary>
        public event DataConvertDelegate AfterConvert;

        /// <summary>
        /// 转换中事件
        /// </summary>
        public event DataConvertProcessDelegate Converting;

        /// <summary>
        /// 暴露出的函数
        /// 用来创建任务名称
        /// 基类可以根据自己的需求直接重写
        /// </summary>
        /// <returns></returns>
        protected virtual string CreateName()
        {
            return $"{DateTimeUtils.GetCurrentDateString()}({UUIDUtils.CreateUUID()})";
        }

        /// <summary>
        /// 检查任务
        /// </summary>
        public virtual void Check()
        {
            try
            {
                OnBeforeCheck();
                AddInfoLogItem(string.Format("开始检查任务"));
                OnBeforeCheckEvent(new DataConvertEventArgs(this));
                TaskStatus = TaskStatus.Checking;
                if (InputDatasource.SourceType == SourceType.UnKnow)
                {
                    throw new FileNotFoundException($"输入的文件或路径不存在，{InputDatasource.Source}");
                }
                Name = CreateName();
                OnCheck();
                TaskStatus = TaskStatus.Checked;
                OnAfterCheckEvent(new DataConvertEventArgs(this));
                AddInfoLogItem(string.Format("检查任务({0})完成", Name));
            }
            catch (System.Exception ex)
            {
                TaskStatus = TaskStatus.Error;
                OnAfterConvertEvent(new DataConvertEventArgs(this));
                AddErrorLogItem($"检查任务{Name}错误:{ex.Message}");
                throw new System.Exception($"检查任务错误:{ex.Message}");
            }
            finally
            {
                OnAfterCheck();
            }
        }

        /// <summary>
        /// 暴露的函数
        /// 具体实现逻辑重写次函数
        /// </summary>
        protected virtual void OnCheck()
        {

        }

        /// <summary>
        /// 检查数据源之前的流程
        /// </summary>
        protected virtual void OnBeforeCheck()
        {
            this.DataConvertLog.Clear();
        }

        /// <summary>
        /// 检查dwg元数据
        /// </summary>
        protected virtual void OnAfterCheck()
        {

        }

        /// <summary>
        /// 抽象类实现转换函数
        /// </summary>
        public virtual void Convert()
        {
            try
            {
                OnBeforeConvert();
                AddInfoLogItem($"开始转换任务({Name})");
                OnBeforeConvertEvent(new DataConvertEventArgs(this));
                TaskStatus = TaskStatus.Running;
                OnConvert();
                TaskStatus = TaskStatus.Complate;
                OnAfterConvertEvent(new DataConvertEventArgs(this));
                AddInfoLogItem($"转换任务完成({Name})");
            }
            catch (System.Exception ex)
            {
                TaskStatus = TaskStatus.Error;
                OnAfterConvertEvent(new DataConvertEventArgs(this));
                AddErrorLogItem($"转换任务{Name}失败:{ex.Message}");
                throw new System.Exception($"转换任务失败:{ex.Message}");
            }
            finally
            {
                OnAfterConvert();
            }
        }

        /// <summary>
        /// 转换前
        /// </summary>
        protected virtual void OnBeforeConvert()
        {

        }

        /// <summary>
        /// 转换后
        /// </summary>
        protected virtual void OnAfterConvert()
        {

        }

        /// <summary>
        /// 暴露的函数
        /// 具体实现逻辑重写次函数
        /// </summary>
        protected virtual void OnConvert()
        {

        }

        /// <summary>
        /// 检查之前事件
        /// </summary>
        /// <param name="dataConvertArgs"></param>
        protected virtual void OnBeforeCheckEvent(DataConvertEventArgs dataConvertArgs)
        {
            if (BeforeCheck != null)
            {
                BeforeCheck(dataConvertArgs);
                if (dataConvertArgs.Cancle)
                {
                    throw new ConvertAbortException(this);
                }
            }
        }

        /// <summary>
        /// 检查中事件
        /// </summary>
        /// <param name="dataConvertArgs"></param>
        protected virtual void OnCheckingEvent(DataConvertProcessEventArgs dataConvertArgs)
        {
            if (Checking != null)
            {
                Checking(dataConvertArgs);
                if (dataConvertArgs.Cancle)
                {
                    throw new ConvertAbortException(this);
                }
            }
        }

        /// <summary>
        /// 检查完成事件
        /// </summary>
        /// <param name="dataConvertArgs"></param>
        protected virtual void OnAfterCheckEvent(DataConvertEventArgs dataConvertArgs)
        {
            if (AfterCheck != null)
            {
                AfterCheck(dataConvertArgs);
                if (dataConvertArgs.Cancle)
                {
                    throw new ConvertAbortException(this);
                }
            }
        }

        /// <summary>
        /// 转换之前事件
        /// </summary>
        /// <param name="dataConvertArgs"></param>
        protected virtual void OnBeforeConvertEvent(DataConvertEventArgs dataConvertArgs)
        {
            if (BeforeConvert != null)
            {
                BeforeConvert(dataConvertArgs);
                if (dataConvertArgs.Cancle)
                {
                    throw new ConvertAbortException(this);
                }
            }
        }

        /// <summary>
        /// 转换中事件
        /// </summary>
        /// <param name="dataConvertArgs"></param>
        protected virtual void OnConvertingEvent(DataConvertProcessEventArgs dataConvertArgs)
        {
            if (Converting != null)
            {
                Converting(dataConvertArgs);
                if (dataConvertArgs.Cancle)
                {
                    throw new ConvertAbortException(this);
                }
            }
        }

        /// <summary>
        /// 转换完成事件
        /// </summary>
        /// <param name="dataConvertArgs"></param>
        protected virtual void OnAfterConvertEvent(DataConvertEventArgs dataConvertArgs)
        {
            if (AfterConvert != null)
            {
                AfterConvert(dataConvertArgs);
                if (dataConvertArgs.Cancle)
                {
                    throw new ConvertAbortException(this);
                }
            }
        }

        /// <summary>
        /// 添加信息日志
        /// </summary>
        /// <param name="info"></param>
        protected virtual void AddInfoLogItem(string info)
        {
            DataConvertLog.Add(new InfoLogItem(info));
        }

        /// <summary>
        /// 添加警告信息
        /// </summary>
        /// <param name="info"></param>
        protected virtual void AddWraingLogItem(string info)
        {
            DataConvertLog.Add(new WraingLogItem(info));
        }

        /// <summary>
        /// 添加错误信息
        /// </summary>
        /// <param name="info"></param>
        protected virtual void AddErrorLogItem(string info)
        {
            DataConvertLog.Add(new ErrorLogItem(info));
        }
    }
}
